/*
 * Copyright (C) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cmsis_os2.h>
#include <unistd.h> 
#include "lwip/sockets.h"
#include "HiSpark_WiFi_IoT_SSL_VER.h"
#include "oled_ssd1306.h"

extern int new_fd,sock_fd,is_accepted;
extern osMutexId_t g_mutexId;
int red_status=0;       //红灯表示开启
int yellow_status=0;    //黄灯表示暂停
int green_status=0;     //绿灯表示结束
int beep_status=0;
int oven_time=0;    //上报时间

Oven_Params oven_params;


/*软件定时器的回调函数*/
void timeout_periodic(void *arg) {
    (void)arg;
    if(oven_params.start_flag == 1)
    {
        oven_params.time--;
        if(oven_params.time == 0)
        {
            oven_params.start_flag = 0;
        }
    }

}
/**************************************************
 * 任务：TimerTask
 * 使用osTimerNew创建一个100个时钟周期调用一次回调函数timeout_periodic定时器，
 * 每隔100个时钟周期检查一下全局变量time是否小于10，若不小于10则停止时钟周期
 * ***********************************************/
void TimerTask(void *arg) {
    (void)arg;
    osTimerId_t periodic_tid = osTimerNew(timeout_periodic, osTimerPeriodic, NULL, NULL);
    osTimerStart(periodic_tid, 100);
}

/**************************************************
 * 任务：stop_oven
 * 停止烤箱
 * ***********************************************/
void stop_oven(void){
    RedLightStatusSet(OFF);
    YellowLightStatusSet(OFF);
    GreenLightStatusSet(ON);
    for(int num = 0;num < 3; num++ ){
        BeepStatusSet(ON);
        osDelay(50);
        BeepStatusSet(OFF);
    }
    osDelay(100);
    GreenLightStatusSet(OFF);
}
/**************************************************
 * 任务：suspend_oven
 * 暂停烤箱
 * ***********************************************/
void suspend_oven(void){
    RedLightStatusSet(OFF);
    GreenLightStatusSet(OFF);
    YellowLightStatusSet(ON);
    BeepStatusSet(ON);
    osDelay(50);
    BeepStatusSet(OFF);
}
/**************************************************
 * 任务：refresh_led
 * 刷新LED
 * ***********************************************/
void refresh_led(void){
    OledInit();
    OledFillScreen(0);
    char temp[32] = {0};
    oven_params.low=0;
    oven_params.middle=0;
    oven_params.hight=0;
    //显示初始化
    memset(temp,0,sizeof(temp));
    snprintf(temp,sizeof(temp),"STATUS:");
    OledShowString(0,0,temp,1);

    memset(temp,0,sizeof(temp));
    snprintf(temp,sizeof(temp),"TIME:");
    OledShowString(0,2,temp,1);

    memset(temp,0,sizeof(temp));
    snprintf(temp,sizeof(temp),"FIRE:low ");
    OledShowString(0,4,temp,1);
    while (1)
    {
        //刷新状态
        memset(temp,0,sizeof(temp));
        if(yellow_status == 1){
            snprintf(temp,sizeof(temp),"STATUS:SUSPEND");
            yellow_status=0;
        }
        if(green_status == 1){
            snprintf(temp,sizeof(temp),"STATUS:STOP   ");
            green_status=0;
        }
        OledShowString(0,0,temp,1);
        osDelay(20);
        //刷新火力
        memset(temp,0,sizeof(temp));
        if(oven_params.low == 1){
            snprintf(temp,sizeof(temp),"FIRE:low   ");
            oven_params.low=0;
        }
        if(oven_params.middle == 1){
            snprintf(temp,sizeof(temp),"FIRE:middle  ");
            oven_params.middle=0;
        }
        if(oven_params.hight == 1){
            snprintf(temp,sizeof(temp),"FIRE:hight  ");
            oven_params.hight=0;
        }
        OledShowString(0,4,temp,1);
        osDelay(20);
        //刷新时间
        while (oven_params.time > 0 && oven_params.start_flag == 1){
            memset(temp,0,sizeof(temp));
            snprintf(temp,sizeof(temp),"STATUS:START   ");
            OledShowString(0,0,temp,1);

            RedLightStatusSet(ON);
            memset(temp,0,sizeof(temp));
            snprintf(temp,sizeof(temp),"TIME:%d    ",oven_params.time);
            OledShowString(0,2,temp,1);
            oven_time = oven_params.time;
            if(oven_params.time == 0){  //烘烤时间结束                
                memset(temp,0,sizeof(temp));
                snprintf(temp,sizeof(temp),"STATUS:STOP   ");
                OledShowString(0,0,temp,1);
                memset(temp,0,sizeof(temp));
                snprintf(temp,sizeof(temp),"TIME:%d    ",oven_params.time);
                OledShowString(0,2,temp,1);                
                stop_oven();
            }
        }
        //烘烤时间清零
        if(oven_params.start_flag == 2){   
            memset(temp,0,sizeof(temp));
            snprintf(temp,sizeof(temp),"STATUS:STOP   ");
            OledShowString(0,0,temp,1);
            oven_params.start_flag = 0;
            oven_params.time = 0;
            oven_time = oven_params.time;
            memset(temp,0,sizeof(temp));
            snprintf(temp,sizeof(temp),"TIME:%d    ",oven_params.time);
            OledShowString(0,2,temp,1);
            stop_oven();
            oven_params.start_flag = 0;
        }
    }
    osDelay(20);
}


/**************************************************
 * 任务：deal_command_task
 * 命令处理任务
 * ***********************************************/
int deal_command_task(void)
{
    osMutexAcquire(g_mutexId, osWaitForever);
    char recvbuf[512];
    //客户端地址信息
	struct sockaddr_in client_sock;
	int sin_size;
    /*初始化参数*/
    oven_params.start_flag = 0;
    while (1)
    {        
        printf("start accept\n");
        //调用accept函数从队列中
        sin_size = sizeof(struct sockaddr_in);

        if ((new_fd = accept(sock_fd, (struct sockaddr *)&client_sock, (socklen_t *)&sin_size)) == -1)
        {
            perror("accept");
        }
        printf("accept succeed\n");
        is_accepted = 1;
        while (1)
        {   
            bzero(recvbuf, sizeof(recvbuf));
            //接收数据,并根据命令对相应的设备执行控制命令
            if (recv(new_fd, recvbuf, sizeof(recvbuf), 0) < 0)
            {
                printf("recv error\n");
                close(new_fd);
                is_accepted = 0;
                break;
            }
            else
            {   
                //开始烘烤
                if (NULL != strstr(recvbuf, "START"))
                {
                    //定时时间
                    if (NULL != strstr(recvbuf, "TIME"))
                    {
                        if (NULL != strstr(recvbuf, "5")){  
                            oven_params.time = 5;
                        }
                        if (NULL != strstr(recvbuf, "8")){ 
                            oven_params.time = 8;
                        }
                        if (NULL != strstr(recvbuf, "10")){
                            oven_params.time = 10;
                        }
                        if (NULL != strstr(recvbuf, "20")){
                            oven_params.time = 20;
                        }
                    }
                    //火候
                    if(NULL != strstr(recvbuf, "FIRE")){
                        if (NULL != strstr(recvbuf, "low")){
                            oven_params.low = 1;
                        }
                        if (NULL != strstr(recvbuf, "middle")){
                            oven_params.middle = 1;
                        }
                        if (NULL != strstr(recvbuf, "hight")){
                            oven_params.hight = 1;
                        }
                    }
                    //控制LED显示时间
                    red_status = 1;
                    oven_params.start_flag = 1;
                }
                //结束烘烤
                else if(NULL != strstr(recvbuf, "STOP")){
                    oven_params.time=0;
                    green_status=1;
                    oven_params.start_flag = 2;     //标志为2时，时间清零
                    beep_status=1;
                    stop_oven();                    
                }   
                //暂停烘烤
                else if(NULL != strstr(recvbuf, "SUSPEND")){
                    yellow_status=1;
                    oven_params.start_flag = 0;     //标志为0时，时间暂停
                    beep_status=1;
                    suspend_oven();
                }   
            }                         
        }
    }
    osMutexRelease(g_mutexId);
}
